package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import modelo.Cliente;

import conexao.ConnectionManager;

/**
 * @author Carlos, Derek e Hellen
 */
class ClienteDAOImp implements ClienteDAO {
	
	private final String INSERT = "insert into cliente (nome, login, senha, dataNascimento, cpf, telefone, endereco, complemento, bairro, cep, sexo) values (?,?,?,?,?,?,?,?,?,?,?)";
	private final String UPDATE = "update cliente set nome = ?, login = ?, senha = ?, dataNascimento = ?, cpf = ?, telefone = ?, endereco = ?, complemento = ?, bairro = ?, cep = ?, sexo = ? where idCliente = ?";
	private final String DELETE = "delete from cliente where idCliente = ?";
	private final String ALL = "select idCliente, nome, login, senha, dataNascimento, cpf, telefone, endereco, complemento, bairro, cep, sexo from cliente";
	private final String LIKE = "select idCliente, nome, login, senha, dataNascimento, cpf, telefone, endereco, complemento, bairro, cep, sexo from cliente where nome like ?";

	private ConnectionManager connectionManager;
	private static Connection connection;

	ClienteDAOImp() {
		this.openConnection();
	}

	public boolean isConnectionClose() {
		try {
			return connection.isClosed();
		} catch (SQLException ex) {
			return false;
		}
	}

	public void openConnection() {
		if (connectionManager == null) {
			connectionManager = ConnectionManager.getInstance();
		}

		if (connection == null) {
			connection = connectionManager.getConnection();
		}

		if (isConnectionClose()) {
			connection = connectionManager.getConnection();
		}
	}

	public void closeConnection() {
		if (connection != null && connectionManager != null) {
			if (!this.isConnectionClose()) {
				connectionManager.closeConnection(connection);
			}
		}
	}

	public Cliente salvar(Cliente c) {
		try {
			PreparedStatement ps = null;
			// 1 crie um instancia de PreparedStatement
			// para obter a chave gerada pelo banco
			ps = connection.prepareStatement(INSERT);

			ps.setObject(1, c.getNome());
			ps.setObject(2, c.getLogin());
			ps.setObject(3, c.getSenha());
			ps.setObject(4, c.getDataNascimento());
			ps.setObject(5, c.getCpf());
			ps.setObject(6, c.getTelefone());
			ps.setObject(7, c.getEndereco());
			ps.setObject(8, c.getComplemento());
			ps.setObject(9, c.getBairro());
			ps.setObject(10, c.getCep());
			ps.setObject(11, c.getSexo());

			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}
		return c;
	}

	public void alterar(Cliente c) {
		PreparedStatement ps = null;
		try {
			// 2 crie uma instancia de PreparedStatement
			// passe para ela a instrucao para realizar alteracoes em uma
			// registro do banco
			ps = connection.prepareStatement(UPDATE);

			ps.setObject(1, c.getNome());
			ps.setObject(2, c.getLogin());
			ps.setObject(3, c.getSenha());
			ps.setObject(4, c.getDataNascimento());
			ps.setObject(5, c.getCpf());
			ps.setObject(6, c.getTelefone());
			ps.setObject(7, c.getEndereco());
			ps.setObject(8, c.getComplemento());
			ps.setObject(9, c.getBairro());
			ps.setObject(10, c.getCep());
			ps.setObject(11, c.getSexo());
			ps.setObject(12, c.getIdCliente());

			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}
	}

	public void deletar(Cliente c) {
		try {
			PreparedStatement ps = null;
			ps = connection.prepareStatement(DELETE);
			// 3 passe para o PreparedStatement o valor do id que deve ser
			// excluido do banco de dados
			ps.setObject(1, c.getIdCliente());

			ps.executeUpdate();

		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}
	}

	public List<Cliente> findAll() {
		List<Cliente> clientes = new ArrayList<Cliente>();

		try {
			PreparedStatement ps = null;
			ResultSet rs = null;
			ps = connection.prepareStatement(ALL);

			// 4 Obtenha uma instancia de resultset
			rs = ps.executeQuery();

			while (rs.next()) {
				Cliente cliente = new Cliente();
				cliente.setIdCliente(rs.getInt(1));
				cliente.setNome(rs.getString(2));
				cliente.setLogin(rs.getString(3));
				cliente.setSenha(rs.getString(4));
				cliente.setDataNascimento(rs.getDate(5));
				cliente.setCpf(rs.getString(6));
				cliente.setTelefone(rs.getString(7));
				cliente.setEndereco(rs.getString(8));
				cliente.setComplemento(rs.getString(9));
				cliente.setBairro(rs.getString(10));
				cliente.setCep(rs.getString(11));
				cliente.setSexo(rs.getString(12));

				clientes.add(cliente);
				// 5 crie uma instancia de cidade com os dados
				// obtidos do banco e adicione a lista de cidades

			}

		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE,
					null, ex);
		} finally {
			this.closeConnection();
		}
		return clientes;
	}

	@Override
	public List<Cliente> buscaClientePorNome(Cliente cliente) {
		
		List<Cliente> clientes = new ArrayList<Cliente>();
		PreparedStatement ps = null;
		ResultSet rs = null;

		try {
			ps = connection.prepareStatement(LIKE);
			// 6 informe o parametro para instrucao like
			ps.setObject(1, cliente.getNome());

			rs = ps.executeQuery();

			while (rs.next()) {
				clientes.add(new Cliente(rs.getInt("idCliente"), 
						rs.getString("nome"), 
						rs.getString("login"), 
						rs.getString("senha"), 
						rs.getDate("dataNascimento"), 
						rs.getString("cpf"), 
						rs.getString("telefone"),
						rs.getString("endereco"),
						rs.getString("complemento"),
						rs.getString("bairro"),
						rs.getString("cep"),
						rs.getString("sexo")));

			}

		} catch (SQLException ex) {
			Logger.getLogger(ClienteDAOImp.class.getName()).log(Level.SEVERE, null,
					ex);
		} finally {
			this.closeConnection();
		}
		return clientes;
		
	}

}
